#ifndef TIPOCOLEC_H_
#define TIPOCOLEC_H_

#include "tipo_dato_compuesto.h"

/*****************************************************************
 *	tipo_colec.h
 * 
 *  Descripcion: Clase que representa un conjunto de tipos_datos,
 *  similares a un tipo_dato modelo.
 *  En si representa un dato polivalente.
 * **************************************************************/

class TipoColec : public TipoDatoCompuesto {

	private:
		TipoDato* tipo_modelo; //Determina la estructura base de la coleccion
	
	public:
	
	/*
	 * Constructor default: Crea una coleccion vacia, recibe como param
	 * el tipo modelo.
	 */
	TipoColec(const TipoDato &tipo_modelo, bool obligatorio);
	
	/*
	 * Destructor: Libera la mem consumida por la coleccion.
	 */
	~TipoColec();
	
	
	/*
	 * Set obligatorio
	 */
	void set_obligatorio(bool estado);
	
	/*
	 * Get Tipo Modelo: Devuelve una copia del tipo de dato modelo de la
	 * coleccion, para que pueda ser llenado. Tiene que ser liberado
	 * externamente.
	 */
	TipoDato* get_tipo_modelo() const;
	
	/*
	 * Mismo tipo: Devuelve true si los 2 datos son del mismo tipo,
	 * false en caso contrario.
	 */
	virtual bool mismo_tipo(const TipoDato& dato) const;
	
	/*
	 * Busca un dato adentro de la coleccion si lo encuentar devuelve true
	 * de lo contrario false. 
	 */
	bool buscar_dato(const TipoDato& dato) const;
		 
	/* 
	 * Op de insercion: Permite asignar un valor al objeto del tipodato.
	 * Verifica que el dato pasado por param sea una coleccion igual a la actual.
	 * Si hay problemas con el casteo tira una excep.
	 */
	virtual TipoDato& operator= (const TipoDato& dato) throw (ExcepErrorTipos);
	
	/*
	 * Op de igualacion: Devuelve true si los valores de los datos son
	 * iguales, false en caso contrario.
	 * Verifica que el dato pasado por param sea una coleccion igual a la actual..
	 * Si hay problemas con el casteo tira una excep.
	 */
	virtual bool operator== (const TipoDato& dato) const throw (ExcepErrorTipos);
	
	/*
	 * Op <: Devuelve true si el valor del dato actual es menor al del
	 * pasado por param, false en caso contrario.
	 * Verifica que el dato pasado por param sea una coleccion igual a la actual.
	 * Si hay problemas con el casteo tira una excep.
	 */
	virtual bool operator< (const TipoDato& dato) const throw (ExcepErrorTipos);
	
	/*
	 * Get Codigo Tipo: Devuelve el codigo del tipo de dato en cuestion.
	 */
	virtual CodTipo get_codigo_tipo() const;
	
	/*
	 * Add Dato: Agrega el dato pasado como param a la estructura
	 * Devuelve true si lo pudo agregar, false en caso contrario.
	 */
	virtual bool add_dato(const TipoDato  & dato);
	 
	 /*
	  * Quitar dato: Permite quitar el dato ubicado la pos pasada como param
	  * dentro de la estructura.
	  * Devuelve true si lo pudo quitar, false en caso contrario.
	  */
	 virtual bool quitar_dato(unsigned int ind);
	  
	  /*
	   * Operador []: Devuelve el dato que se encuentra en la pos
	   * determinada por el indice pasado como param.
	   * Si el indice cae fuera del tamanio de la estructura,
	   * arroja una excepcion.
	   */
	  virtual TipoDato& operator[] (size_t indice) throw (ExcepIndiceDesbordado);
	
	/*
	 * Clonar: Devuelve la referencia a un nuevo dato con el mismo 
	 * contenido que el actual.
	 * El nuevo objeto es creado en heap y debe ser liberado.
	 */
	virtual TipoDato* clonar() const;
	
	/*
	 * get_tamanio: Devuelve la cantidad de campos del tipo.
	 */
	virtual unsigned int get_tamanio() const;
	
	/*
	 * ToStream: Dado un stream de salida, pasa la representacion del dato
	 * al mismo.
	 */
	virtual ostream& toStream(ostream& out) const;
	
	/*
	 * Crea una cadena que contiene el dato serializado. La devuelve
	 * en retorno y asigna el tamano de la misma en tam
	 */ 
	virtual void serializar(char ** retorno, unsigned int &tam);
	
	/*
	 * Obtiene un tipo de dato a partir de los datos serializados.
	 * Debe recibir el tamano de tamano de la cadena de serializados.
	 * Devuelve true si pudo realizar bien la operacion, false en
	 * caso contrario
	 */ 
	virtual bool deserializar(char * serializados, unsigned int tam);
	
	
};

#endif

